home *** CD-ROM | disk | FTP | other *** search
/ Aminet 22 / Aminet 22 (1997)(GTI - Schatztruhe)[!][Dec 1997].iso / Aminet / docs / mags / DC4_Guide.lha / DC4_Guide / Mag4_Guide / RAYCASTER.AMOS / RAYCASTER.amosSourceCode < prev    next >
Encoding:
AMOS Source Code  |  1997-08-22  |  10.7 KB  |  493 lines

  1. '  RayCaster 3D engine for DoubleClick Issue 4 
  2. '    ï¿½1997 Mark Harman 
  3. '  You may use/modify this code as you wish
  4.  
  5. Set Buffer 160
  6. Degree 
  7.  
  8. _SW=160 : Rem screen width 
  9. _SH=_SW/1.6 : Rem screen height
  10.  
  11. Dim _SIN(4096),_COS(4096),_COSEC(4096),_SEC(4096) : Rem tables for sin, cosine, cosec and sec
  12. Dim _DIST(4096,4) : Rem 0,1=x,y, 2=dist 3=map, 4=sliv - speed up 
  13. _MX=32 : _MY=32 : Rem size of map in 'blocks'
  14. Dim _MAP(_MX,_MY) : Rem Map data 
  15.  
  16. 'set initial variables 
  17. BSIZE=80 : Rem size of each block or square 
  18. YHEIGHT=0 : Rem NOT USED at the moment 
  19. HALFBSIZE=BSIZE/2 : Rem Precalculated for extra speed
  20. _LIGHTDIST=6*BSIZE : Rem Viewing distance 
  21. DEGANG=180 : Rem Initial View Direction in DEGREES
  22. _ANGOA=0 : Rem NOT USED at the moment 
  23. POSX=BSIZE+HALFBSIZE : Rem player's x pos 
  24. POSY=BSIZE+HALFBSIZE : Rem and y pos
  25. _SCX=0 : Rem NOT USED 
  26. _SCY=100 : Rem NOT USED 
  27. _WALLHEIGHT=BSIZE*128*_SH : Rem height of a wall (independant of distance) 
  28. '_DUCKED=0 
  29.  
  30. Gosub _CALCTABLES
  31. Gosub _GETMAP
  32.  
  33. Screen Open 0,320,200,16,Lowres
  34. Paper 0 : Cls : Flash Off : Curs Off 
  35. Double Buffer : Autoback 0
  36. Gosub _GETRAINBOW
  37. Screen Open 1,320,200,16,Lowres
  38. Screen Hide 1
  39. Paper 0 : Cls : Flash Off : Curs Off 
  40. Dim _BOBX(Length(1)),_BOBY(Length(1))
  41. For K=1 To Length(1)
  42.    X=((K-1) mod 5)*BSIZE
  43.    Y=(K-1)/5*BSIZE
  44.    Paste Bob X,Y,K
  45.    _BOBX(K)=X
  46.    _BOBY(K)=Y
  47. Next 
  48. Screen 0
  49. Colour 3,0
  50.  
  51. _MLOOP:
  52. PIXSX=2
  53. If Prg State=-1
  54.    PIXSX=2
  55. End If 
  56. _FRAMERATE=-1
  57. '  Rate at 160x100, PX1
  58.  
  59. _XBOUNDSTART=POSX/BSIZE*BSIZE
  60. _YBOUNDSTART=POSY/BSIZE*BSIZE
  61. Do 
  62.    'draw screen 
  63.    Timer=0
  64.    Ink 0
  65.     Extension_12_01A0 0,0
  66.     Extension_12_01B0 _SW,200
  67.    DANG=-_HSW+_ANGLES
  68.    For VX=0 To _SW-1 Step PIXSX
  69.       'DANG=VX-_HSW
  70.       'DANG=((2.0*VX)/_SW-1)*_VIEWANG
  71.       'DDANG=(((2.0*VX)/_SW-1)*_VIEWANGDEG)
  72.       CANG=(ANG+DANG+ANGOA+_ANGLES) mod _ANGLES
  73.       _NEWCAST[POSX,POSY,CANG]
  74.       'DANG=(DANG+_ANGLES) mod _ANGLES 
  75.       NEWCAST=Max(NEWCAST,1)
  76.       'NHS=_WALLHEIGHT/(Max(NEWCAST*_COS(DANG),512)) 
  77.       NHS=_WALLHEIGHT/(NEWCAST*_COS(DANG))
  78.       
  79.       '_WALLY=_HSH+YHEIGHT/NEWCAST 
  80.       '      If _WALLY-NHS>=0 and _WALLY+NHS<_SH and NEWCAST<=_LIGHTDIST 
  81.       If _HSH-NHS>=0 and _HSH+NHS<_SH and NEWCAST<=_LIGHTDIST
  82.          X=_BOBX(MAP)
  83.          Y=_BOBY(MAP)
  84.          'Zoom 1,X+SLIV,Y,X+SLIV+1,Y+BSIZE-1 To 0,VX,_WALLY-NHS,VX+PIXSX,_WALLY+NHS 
  85.          Zoom 1,X+SLIV,Y,X+SLIV+1,Y+BSIZE-1 To 0,VX,_HSH-NHS,VX+PIXSX,_HSH+NHS
  86.          '_ZOOM[1,SLIV,0,SLIV+1,31,0,VX,100-NHS,VX+PIXSX,100+NHS] 
  87.       Else 
  88.          If NEWCAST>_LIGHTDIST
  89.             Ink 3
  90.              Extension_12_01A0 VX,_HSH-NHS
  91.              Extension_12_01B0 PIXSX,2*NHS
  92.          Else 
  93.             X=_BOBX(MAP)
  94.             Y=_BOBY(MAP)+HALFBSIZE
  95.             ZDY=Max(1,(HALFBSIZE*_HSH)/NHS)
  96.             Zoom 1,X+SLIV,Y-ZDY,X+SLIV+1,Y+ZDY-1 To 0,VX,0,VX+PIXSX,_SH
  97.          End If 
  98.       End If 
  99.       
  100.       Add DANG,PIXSX,0 To _ANGLES-PIXSX
  101.    Next 
  102.    TIME=Timer
  103.    If _FRAMERATE=-1
  104.       Trap Print 50.0/TIME
  105.       Home 
  106.    End If 
  107.    Screen Swap 
  108.    Wait Vbl 
  109.    If Key Shift and 3
  110.       SHIFT=4
  111.    Else 
  112.       SHIFT=2
  113.    End If 
  114.    If Key Shift and 192
  115.       SIDE=1
  116.    Else 
  117.       SIDE=0
  118.    End If 
  119.    If Key State(79)
  120.       'left
  121.       If SIDE=0
  122.          Add ANG,-4*TIME
  123.          If ANG<0
  124.             Add ANG,_ANGLES
  125.          End If 
  126.       Else 
  127.          DX=-(_COS(ANG)*TIME*SHIFT)/340
  128.          DY=-(_SIN(ANG)*TIME*SHIFT)/340
  129.          NX=POSX+DX
  130.          NY=POSY+DY
  131.          Gosub _CHECKMOVE
  132.       End If 
  133.    Else If Key State(78)
  134.       'right 
  135.       If SIDE=0
  136.          Add ANG,4*TIME
  137.          If ANG>=_ANGLES
  138.             Add ANG,-_ANGLES
  139.          End If 
  140.       Else 
  141.          DX=(_COS(ANG)*TIME*SHIFT)/680
  142.          DY=(_SIN(ANG)*TIME*SHIFT)/680
  143.          NX=POSX+DX
  144.          NY=POSY+DY
  145.          Gosub _CHECKMOVE
  146.       End If 
  147.    End If 
  148.    If Key State(76)
  149.       'forward 
  150.       'If _DUCKED=0
  151.       'Add YHEIGHT,300,0 To 300
  152.       'Else  
  153.       'SHIFT=SHIFT/2 
  154.       'End If  
  155.       DX=(_SIN(ANG)*TIME*SHIFT)/340
  156.       DY=-(_COS(ANG)*TIME*SHIFT)/340
  157.       NX=POSX+DX
  158.       NY=POSY+DY
  159.       Gosub _CHECKMOVE
  160.    Else If Key State(77)
  161.       'backwards 
  162.       'If _DUCKED=0
  163.       'Add YHEIGHT,300,0 To 300
  164.       'Else  
  165.       'SHIFT=SHIFT/2 
  166.       'End If  
  167.       DX=-(_SIN(ANG)*TIME*SHIFT)/340
  168.       DY=(_COS(ANG)*TIME*SHIFT)/340
  169.       NX=POSX+DX
  170.       NY=POSY+DY
  171.       Gosub _CHECKMOVE
  172.    End If 
  173.    ANGOA=0
  174.    If Key State(40)
  175.       ANGOA=_VIEWQ2
  176.    End If 
  177.    If Key State(34)
  178.       _DUCKED=-1-_DUCKED
  179.       YHEIGHT=_DUCKED*800
  180.    End If 
  181.    If Key State(90)
  182.       PIXSX=1
  183.    Else If Key State(91)
  184.       PIXSX=2
  185.    Else If Key State(92)
  186.       PIXSX=4
  187.    Else If Key State(93)
  188.       PIXSX=8
  189.    Else If Key State(74)
  190.       Add _SW,-16,80 To 320
  191.       Add _SH,-10,50 To 200
  192.       Gosub _CALCTABLES
  193.       Cls : Screen Swap : Cls 
  194.       Gosub _GETRAINBOW
  195.    Else If Key State(94)
  196.       Add _SW,16,80 To 320
  197.       Add _SH,10,50 To 200
  198.       Gosub _CALCTABLES
  199.       Cls : Screen Swap : Cls 
  200.       Gosub _GETRAINBOW
  201.    End If 
  202. Loop 
  203. 'T=Timer 
  204. 'Print(_NFRAMES*50.0)/T
  205. 'Screen Swap 
  206. End 
  207.  
  208. _CALCTABLES:
  209. _HSW=_SW/2
  210. _HSH=_SH/2
  211. _VIEWANGDEG=90
  212. If _ANGLES<>0
  213.    DEGANG=(ANG*360)/_ANGLES
  214. End If 
  215. _ANGLES=(360*_SW)/_VIEWANGDEG
  216. ANG=(DEGANG*_ANGLES)/360
  217. _VIEWANG=(_ANGLES*_VIEWANGDEG)/360
  218. _VIEWQ1=_ANGLES/4
  219. _VIEWQ2=2*_ANGLES/4
  220. _VIEWQ3=3*_ANGLES/4
  221.  
  222. STP#=360.0/_ANGLES
  223. CURRANG=0
  224. For K#=0.0 To 360 Step STP#
  225.    S#=Sin(K#)
  226.    C#=Cos(K#)
  227.    _SIN(CURRANG)=S#*512
  228.    _COS(CURRANG)=C#*512
  229.    If S#=0
  230.       S#=0.009
  231.    End If 
  232.    If C#=0
  233.       C#=0.009
  234.    End If 
  235.    _COSEC(CURRANG)=512/S#
  236.    _SEC(CURRANG)=512/C#
  237.    
  238.    _DIST(CURRANG,0)=0
  239.    
  240.    Inc CURRANG
  241. Next 
  242. Return 
  243.  
  244. _GETMAP:
  245. '1=Wall, 2=PSoft 
  246.  
  247. Restore _MAP1
  248. For Y=0 To _MY-1
  249.    Read LINE$
  250.    For X=0 To _MX-1
  251.       MP$=Mid$(LINE$,X+1,1)
  252.       MP=Val(MP$)
  253.       _MAP(X,Y)=MP
  254.    Next 
  255. Next 
  256.  
  257. _MAP1:
  258. Data "11111111111111111111111111111111"
  259. Data "10100000100000110000111111111111"
  260. Data "10100000000000000000011111111111"
  261. Data "10100000100000110000111111111111"
  262. Data "10112110111111111111111111111111"
  263. Data "10000000000000000000000000000001"
  264. Data "11111011111111111111111110111101"
  265. Data "11100001100000000000001100011101"
  266. Data "11100001100001110000001100011101"
  267. Data "11100001100001110000001100011001"
  268. Data "11100001100011111111111111111001"
  269. Data "11111111110110000001111111110001"
  270. Data "11100011000000000000000000000001"
  271. Data "11100000000000000000000000000001"
  272. Data "11110111111011111111011111101111"
  273. Data "11110111111111111111111111111111"
  274. Data "11110111111111111111111111111111"
  275. Data "11110111111111111111111111111111"
  276. Data "11110000000000000000011111111111"
  277. Data "11111100000000000000011111111111"
  278. Data "11111100200000000020011111111111"
  279. Data "11111100000000000000011111111111"
  280. Data "11111100000011100000011111111111"
  281. Data "11111100000010100000011111111111"
  282. Data "11111100000000000000011111111111"
  283. Data "11111100200000000020011111111111"
  284. Data "11111100000000000000011111111111"
  285. Data "11111100000000000000011111111111"
  286. Data "11111111101111111011111111111111"
  287. Data "11111111000111110001111111111111"
  288. Data "11111111000111110001111111111111"
  289. Data "11111111111111111111111111111111"
  290.  
  291. Return 
  292.  
  293. _GETRAINBOW:
  294. Clip 0,0 To _SW,_SH
  295. Rainbow Del 0
  296. Set Rainbow 0,0,_SH,"","",""
  297. For K=0 To _HSH-1
  298.    C=(Ln(((K+1)*200)/_HSH)*2)
  299.    C=Max(0,C-4)
  300.    Rain(0,_HSH-1-K)=C*273+3
  301.    Rain(0,_HSH+K)=C*273+544
  302. Next 
  303. Rainbow 0,0,50,_SH
  304.  
  305. Return 
  306.  
  307. _CHECKMOVE:
  308. OKAY=-1
  309. MAPX=NX/BSIZE
  310. MAPY=NY/BSIZE
  311. MP=_MAP(MAPX,MAPY)
  312. If MP>0
  313.    OKAY=0
  314.    'put to furthest available 
  315.    'If DY>0 
  316.    '   NY=(Y/BSIZE+1)*BSIZE-1 
  317.    'End If  
  318.    'OKAY=-1 
  319. End If 
  320.  
  321. If OKAY=-1
  322.    POSX=NX
  323.    POSY=NY
  324.    _XBOUNDSTART=POSX/BSIZE*BSIZE
  325.    _YBOUNDSTART=POSY/BSIZE*BSIZE
  326. End If 
  327.  
  328. Return 
  329.  
  330. Procedure _NEWCAST[X,Y,ANG]
  331.    Shared _COS(),_SIN(),_SEC(),_COSEC(),_DIST(),_ANGLES,_MAP(),BSIZE,HALFBSIZE,_LIGHTDIST
  332.    Shared _VIEWQ1,_VIEWQ2,_VIEWQ3
  333.    Shared _XBOUNDSTART,_YBOUNDSTART
  334.    
  335.    'Shared XDEPTH,YDEPTH
  336.    
  337.    '  outputs:
  338.    Shared NEWCAST,MAP,SLIV
  339.    
  340.    If _DIST(ANG,0)=X and _DIST(ANG,1)=Y
  341.       NEWCAST=_DIST(ANG,2)
  342.       MAP=_DIST(ANG,3)
  343.       SLIV=_DIST(ANG,4)
  344.       Pop Proc
  345.    End If 
  346.    'ANGLE=(ANG+_ANGLES) mod _ANGLES 
  347.    'Cls 
  348.    'Print ANG,ANGLE 
  349.    'Wait Key  
  350.    ANGLE=ANG
  351.    CORNER=0
  352.    If ANG>_VIEWQ1 and ANG<_VIEWQ3
  353.       YADJ=HALFBSIZE
  354.    Else 
  355.       YADJ=-HALFBSIZE
  356.    End If 
  357.    If ANG>0 and ANG<_VIEWQ2
  358.       XADJ=HALFBSIZE
  359.    Else 
  360.       XADJ=-HALFBSIZE
  361.    End If 
  362.    
  363.    'pre-calc
  364.    _CANG=_COS(ANGLE)
  365.    _SANG=_SIN(ANGLE)
  366.    _CANGR=_SEC(ANGLE)
  367.    _SANGR=_COSEC(ANGLE)
  368.    'x casting 
  369.    If _CANG=0
  370.       XDEPTH=1E+09
  371.    Else 
  372.       If ANG>_VIEWQ1 and ANG<_VIEWQ3
  373.          YBOUND=_YBOUNDSTART+BSIZE
  374.          YDELTA=BSIZE
  375.       Else 
  376.          YBOUND=_YBOUNDSTART
  377.          YDELTA=-BSIZE
  378.       End If 
  379.       Do 
  380.          
  381.          YDIST=YBOUND-Y
  382.          DEPTH=(YDIST*_CANGR)/512
  383.          XDIST=(DEPTH*_SANG)/512
  384.          DX=(X-XDIST)/BSIZE
  385.          ADEPTH=Abs(DEPTH)
  386.          If ADEPTH>_LIGHTDIST
  387.             XDEPTH=ADEPTH
  388.             Exit 
  389.          End If 
  390.          If DX>=0 and DX<32
  391.             MP=_MAP(DX,(YBOUND+YADJ)/BSIZE)
  392.             If MP>0
  393.                XDEPTH=ADEPTH
  394.                XSLIV=Abs(X-XDIST) mod BSIZE
  395.                XMP=MP
  396.                Exit 
  397.             Else 
  398.                Add YBOUND,YDELTA
  399.             End If 
  400.          Else 
  401.             XDEPTH=1E+06
  402.             Exit 
  403.          End If 
  404.       Loop 
  405.    End If 
  406.    
  407.    'y casting 
  408.    If _SANG=0
  409.       YDEPTH=1E+06
  410.    Else 
  411.       If ANG>0 and ANG<_VIEWQ2
  412.          XBOUND=_XBOUNDSTART+BSIZE
  413.          XDELTA=BSIZE
  414.       Else 
  415.          XBOUND=_XBOUNDSTART
  416.          XDELTA=-BSIZE
  417.       End If 
  418.       Do 
  419.          XDIST=XBOUND-X
  420.          DEPTH=(XDIST*_SANGR)/512
  421.          ADEPTH=Abs(DEPTH)
  422.          If ADEPTH>_LIGHTDIST
  423.             YDEPTH=ADEPTH
  424.             Exit 
  425.          End If 
  426.          YDIST=(DEPTH*_CANG)/512
  427.          DY=(Y-YDIST)/BSIZE
  428.          If DY>=0 and DY<32
  429.             MP=_MAP((XBOUND+XADJ)/BSIZE,DY)
  430.             If MP>0
  431.                YDEPTH=ADEPTH
  432.                YSLIV=Abs(Y-YDIST) mod BSIZE
  433.                YMP=MP
  434.                Exit 
  435.             Else 
  436.                Add XBOUND,XDELTA
  437.             End If 
  438.          Else 
  439.             YDEPTH=1E+06
  440.             Exit 
  441.          End If 
  442.       Loop 
  443.    End If 
  444.    
  445.    If XDEPTH<YDEPTH
  446.       NEWCAST=XDEPTH
  447.       SLIV=XSLIV
  448.       MAP=XMP
  449.       If XSLIV=0
  450.          CORNER=-1
  451.       End If 
  452.    Else 
  453.       NEWCAST=YDEPTH
  454.       SLIV=YSLIV
  455.       MAP=YMP
  456.       If YSLIV=0
  457.          CORNER=-1
  458.       End If 
  459.    End If 
  460.    
  461.    _DIST(ANG,0)=X
  462.    _DIST(ANG,1)=Y
  463.    _DIST(ANG,2)=NEWCAST
  464.    _DIST(ANG,3)=MAP
  465.    _DIST(ANG,4)=SLIV
  466.    'Print X,Y,ANG 
  467.    'Print XDEPTH,YDEPTH,DEPTH,NEWCAST 
  468.    'Print 
  469.    
  470. End Proc
  471.  
  472. Procedure _CALC[YBOUND,Y,_CANG,_SANG,X,BSIZE]
  473.    'YDIST=YBOUND-Y' 
  474.    'DEPTH=(YDIST*512)/_CANG 
  475.    'XDIST=(DEPTH*_SANG)/512 
  476.    'DX=(X-XDIST)/BSIZE
  477.    Dreg(0)=YBOUND
  478.    Dreg(6)=Y
  479.    Dreg(5)=_CANG
  480.    Dreg(2)=_SANG
  481.    Dreg(1)=X
  482.    
  483.    
  484.    Dreg(0)=Dreg(0)-Dreg(6)
  485.    Dreg(0)=(Dreg(0)*512)/Dreg(5)
  486.    Dreg(2)=(Dreg(0)*Dreg(2))/512
  487.    Dreg(1)=(Dreg(1)-Dreg(2))/BSIZE
  488.    
  489.    'DEPTH=Dreg(0) 
  490.    'DX=Dreg(1)
  491.    'XDIST=Dreg(2) 
  492.    
  493. End Proc